package com.cuixichang.minimalism.domain;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cuixichang.minimalism.acl.RelevanceDesign;
import com.cuixichang.minimalism.basal.enums.DefaultNumberEnum;
import com.cuixichang.minimalism.core.mybatis.cnstants.BaseFieldNames;
import com.cuixichang.minimalism.core.security.userdetails.CredentialDetail;
import com.cuixichang.minimalism.service.IRouterRelationService;
import com.cuixichang.minimalism.service.IRouterService;
import com.cuixichang.minimalism.transfer.dto.IRouterDTO;
import com.cuixichang.minimalism.transfer.dto.IRouterRelationDTO;
import com.cuixichang.minimalism.transfer.po.IRouter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class IRouterCommandServiceImpl implements IRouterCommandService{
    @Autowired
    private IRouterService routerService;
    @Autowired
    private IRouterRelationService routerRelationService;
    @Autowired
    private RelevanceDesign relevanceDesign;
    @Override
    public Page<IRouterDTO> selectPageByConditional(IRouterDTO dto, Long pageNo, Long pageSize, CredentialDetail credential) {
        if(Objects.isNull(credential)) return Page.of(pageNo,pageSize);
        Long createLoginId = credential.getLoginId();
        return routerService.selectPage(dto,pageSize,pageNo,(po, queryWrapper) -> {
            if(Objects.nonNull(createLoginId)){
                List<Long> beAuthLoginIds = relevanceDesign.beAuthLoginIds(createLoginId);
                queryWrapper.in(!CollectionUtils.isEmpty(beAuthLoginIds), BaseFieldNames.CREATE_LOGIN_ID, beAuthLoginIds);
            }
            String keyword = dto.getKeyword();
            if(StrUtil.isNotBlank(keyword)){
                queryWrapper.and(warp->{
                    warp.like("router_name",keyword).or().like("router_signboard",keyword);
                });
            }
        });
    }

    @Override
    public boolean deleteByIdHasPreCheck(Long id, String systemCode, CredentialDetail credentialDetail) {
        Assert.notNull(id,"路由Id不能为空,请检查");
        IRouterDTO router = selectByIdHasPreCheck(id, systemCode, credentialDetail);
        if(Objects.isNull(router)) return false;
        routerRelationService.deleteByCondition(IRouterRelationDTO.builder().routerId(id).build());
        return routerService.deleteById(id) == 1;
    }

    @Override
    public IRouterDTO selectByIdHasPreCheck(Long id, String systemCode, CredentialDetail credentialDetail) {
        Assert.notNull(id,"路由Id不能为空,请检查");
        return Optional.ofNullable(credentialDetail).map(credential -> {
            List<Long> beAuthLoginIds = relevanceDesign.beAuthLoginIds(credential.getLoginId());
            IRouterDTO po = routerService.selectOne(IRouterDTO.builder().id(id).createSystemCode(systemCode).build());
            return Optional.ofNullable(po).filter(p-> beAuthLoginIds.contains(p.getCreateLoginId())).orElse(null);
        }).orElse(routerService.selectById(id));
    }

    @Override
    public IRouterDTO insert(IRouterDTO dto, CredentialDetail credentialDetail) {
        Assert.notNull(dto,"路由信息不能为空,请检查");
        Assert.isTrue(allowUseRouter(dto.getRouterUrl(), dto.getRequestType(), dto.getCreateSystemCode(), null),
                "路由地址已存在,请检查");
        dto.setCreateLoginId(Objects.nonNull(credentialDetail)? credentialDetail.getLoginId(): DefaultNumberEnum.Zero.getCode());
        return routerService.insert(dto);
    }

    @Override
    public boolean updateByIdHasPreCheck(IRouterDTO dto, CredentialDetail credential) {
        Assert.notNull(dto,"路由信息不能为空,请检查");
        Long id = dto.getId();
        Assert.notNull(id,"路由Id不能为空,请检查");
        dto.setCreateLoginId(Objects.nonNull(credential)? credential.getLoginId(): DefaultNumberEnum.Zero.getCode());
        IRouterDTO router = selectByIdHasPreCheck(id, dto.getCreateSystemCode(), credential);
        if(Objects.isNull(router)) return false;
        return routerService.updateById(dto) == 1;
    }

    @Override
    public boolean allowUseRouter(String routerUrl, String requestType, String systemCode, Long matchRouterId) {
        Assert.hasText(routerUrl,"路由地址不能为空,请检查");
        Assert.hasText(requestType,"请求方式不能为空,请检查");
        Assert.hasText(systemCode,"系统编码不能为空,请检查");
        IRouterDTO checkRouter = routerService.selectOne(IRouterDTO.builder().routerUrl(routerUrl).requestType(requestType)
                .createSystemCode(systemCode).build());
        return Optional.ofNullable(matchRouterId).map(matchId-> Optional.ofNullable(checkRouter).
                map(po-> matchRouterId.equals(po.getId())).orElse(true)).orElse(Objects.isNull(matchRouterId));
    }
}
